/*********************
* Author:Dzlua
* QQ:505544956
* time:2016/08/21
*/
#include "StringMgr.h"
#include "../utilities/Log.h"

EDUI_NAMESPACE_BEGIN

struct StringMgr::sData {
    String name;
    String text;
    int id;
};

struct StringMgr::sGroup {
    String name;
    DataMap* map;
    sGroup()
    {
        map = new DataMap;
        Assert(map);
    }
    ~sGroup()
    {
        if (map){
            for (DataMap::iterator it = map->begin(); it != map->end(); ++it){
                if(*it){
                    delete (*it);
                    (*it) = 0;
                }
            }
            map->clear();

            delete map;
            map = 0;
        }
    }
};


StringMgr::StringMgr()
{
    m_map = new DataMap;
    Assert(m_map);
    m_group = new GroupMap;
    Assert(m_group);
}

StringMgr::~StringMgr()
{
    this->Clear();
    if (m_map){
        delete m_map;
        m_map = 0;
    }
    if (m_group){
        delete m_group;
        m_group = 0;
    }
}

bool StringMgr::Add(const char* name, const char* text, const char* group, int id)
{
    if (!name || !text) return false;
    if (id < -1) id = -1;

    if (!group){
        //add to global
        if (this->Get(name, 0)) return false;

        sData* sdata = new sData;
        Assert(sdata);
        sdata->name = name;
        sdata->text = text;
        sdata->id = id;

        m_map->push_back(sdata);
    } else {
        sGroup* sgroup = 0;
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                sgroup = (*it);
                break;
            }
        }        
        if (!sgroup){
            sgroup = new sGroup;
            sgroup->name = group;
            m_group->push_back(sgroup);
        }
        //
        for (DataMap::iterator it = sgroup->map->begin(); it != sgroup->map->end(); ++it){
            if((*it) && (*it)->name == name){
                return false;
            }
        }
        sData* sdata = new sData;
        sdata->name = name;
        sdata->text = text;
        sdata->id = id;

        sgroup->map->push_back(sdata);
    }
    return true;
}

void StringMgr::Remove(const char* name, const char* group)
{
    if (!name) return;
    if (!group){
        for (DataMap::iterator it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && ((*it)->name == name)){
                delete (*it);
                (*it) = 0;
                m_map->erase(it);
                return;
            }
        }
    } else {
        sGroup* sgroup = 0;
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                sgroup = (*it);
                break;
            }
        }
        if (!sgroup) return;
        for (DataMap::iterator it = sgroup->map->begin(); it != sgroup->map->end(); ++it){
            if((*it) && ((*it)->name == name)){
                delete (*it);
                (*it) = 0;
                sgroup->map->erase(it);
                return;
            }
        }
    }
}

void StringMgr::Remove(int id, const char* group)
{
    if (id < 0) return;
    if (!group){
        for (DataMap::iterator it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && ((*it)->id == id)){
                delete (*it);
                (*it) = 0;
                m_map->erase(it);
                return;
            }
        }
    } else {
        sGroup* sgroup = 0;
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                sgroup = (*it);
                break;
            }
        }
        if (!sgroup) return;
        for (DataMap::iterator it = sgroup->map->begin(); it != sgroup->map->end(); ++it){
            if((*it) && ((*it)->id == id)){
                delete (*it);
                (*it) = 0;
                sgroup->map->erase(it);
                return;
            }
        }
    }
}

const char* StringMgr::Get(const char* name, const char* group)
{
    if (!name) return 0;
    if (!group){
        for (DataMap::iterator it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && ((*it)->name == name)){
                return (*it)->text.GetString();
            }
        }
    } else {
        sGroup* sgroup = 0;
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                sgroup = (*it);
                break;
            }
        }
        if (!sgroup) return 0;
        for (DataMap::iterator it = sgroup->map->begin(); it != sgroup->map->end(); ++it){
            if((*it) && ((*it)->name == name)){
                return (*it)->text.GetString();
            }
        }
        // group has not,find in global.
        return this->Get(name, 0);
    }
    return 0;
}

const char* StringMgr::Get(int id, const char* group)
{
    if (id < 0) return 0;
    if (!group){
        for (DataMap::iterator it = m_map->begin(); it != m_map->end(); ++it){
            if((*it) && ((*it)->id == id)){
                return (*it)->text.GetString();
            }
        }
    } else {
        sGroup* sgroup = 0;
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                sgroup = (*it);
                break;
            }
        }
        if (!sgroup) return 0;
        for (DataMap::iterator it = sgroup->map->begin(); it != sgroup->map->end(); ++it){
            if((*it) && ((*it)->id == id)){
                return (*it)->text.GetString();
            }
        }
        // group has not,find in global.
        return this->Get(id, 0);
    }
    return 0;
}

int StringMgr::Count(const char* group)
{
    if (!group){
        return (int)m_map->size();
    } else {
        for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
            if((*it) && (*it)->name == group){
                return (int)(*it)->map->size();
            }
        }
    }
    return -1;
}

size_t StringMgr::GroupCount()
{
    return m_group->size();
}

void StringMgr::Clear()
{
    for (DataMap::iterator it = m_map->begin(); it != m_map->end(); ++it){
        if(*it){
            delete (*it);
            (*it) = 0;
        }
    }
    m_map->clear();

    for (GroupMap::iterator it = m_group->begin(); it != m_group->end(); ++it){
        if(*it){
            delete (*it);
            (*it) = 0;
        }
    }
    m_group->clear();
}

EDUI_NAMESPACE_END
